
import {  compareTwoVdom ,findDOM} from './react-dom';

export let updateQueue = {
    isBatchUpdate:false, //来控制更新是同步还是异步
    updaters:[], //更新的数组
    batchUpdate(){ //批量更新
        updateQueue.updaters.forEach(updater=>updater.updateComponent())
        updateQueue.isBatchUpdate = false
        updateQueue.updaters.length = 0
    }
}

class Updater {
    constructor(classInstance){
        this.classInstance = classInstance //也就是类的实例
        this.pendingStates = [];//等待更新队列
    }
    addState(partialState){
        this.pendingStates.push(partialState)
        this.emitUpdate(); //触发更新
    }
    emitUpdate(newProps){
        this.nextProps = newProps
        if(updateQueue.isBatchUpdate){ //说明当前处理批量更新模式
            updateQueue.updaters.push(this)
        }else{
            this.updateComponent();//更新组件
        }
    }
    updateComponent(){
        // debugger
        let {nextProps,classInstance,pendingStates} = this
        // 如果属性或者状态更新都会触发更新
        if(nextProps||pendingStates.length>0){
            shouldUpdate(classInstance,nextProps,this.getState())
        }
    }
    // 基于老状态和pendingState获取新状态
    getState(){
        let { classInstance,pendingStates} = this
        let {state} = classInstance //老状态
        // 更新状态
        pendingStates.forEach((nextState)=>{
            if(typeof nextState === 'function'){
                nextState = nextState(state)
            }
            state = {...state,...nextState}
        })
        pendingStates.length = 0 //清空数组
        return state
    }
}
function shouldUpdate(classInstance,nextProps,nextState){
    let willUpdate = true;
    // 如果有shouldComponentUpdate方法，并且shouldComponentUpdate执行结果是false的话才会willUpdate为false
    if(classInstance.shouldComponentUpdate && !classInstance.shouldComponentUpdate(nextProps,nextState)){
        willUpdate = false
    }
    if(willUpdate && classInstance.componentWillUpdate){
        classInstance.componentWillUpdate()
    }
    if(nextProps){
        classInstance.props = nextProps
    }
    classInstance.state = nextState //不管要不要更新，赋值都会执行
    if(willUpdate){ //如果要更新就更新界面，否则不更新
        classInstance.forceUpdate() //  //让类的实例强行更新
    }
}

    

class Component {
    static isReactComponent = true
    constructor(props){
        this.props = props
        this.state = {}
        this.updater = new Updater(this)
    }
    setState(partialState){
        this.updater.addState(partialState)
    }
    forceUpdate(){
        let oldRenderVdom = this.oldRenderVdom;//之前在mountClassComponent方法中进行过挂载
        // let oldDom = oldRenderVdom.dom
        let oldDom = findDOM(oldRenderVdom)
        if(this.constructor.getDerivedStateFromProps){
            let newState = this.constructor.getDerivedStateFromProps(this.props, this.state);
            if (newState){
                this.state = {
                    ...this.state,
                    ...newState
                }
            }
        }


        let newRenderVdom = this.render(); //重新render()获取新的vdom，使用新的vdom生成新的真实dom，用新的真实dom替换掉老的dom
        let snapshot = this.getSnapshotBeforeUpdate && this.getSnapshotBeforeUpdate();
        // 此处逻辑就是我们的dom diff的逻辑
        compareTwoVdom(oldDom.parentNode, oldRenderVdom, newRenderVdom);
        this.oldRenderVdom = newRenderVdom;
        if(this.componentDidUpdate){
            this.componentDidUpdate(this.props,this.state,snapshot);
        }
    }
}
export default Component